---@class TBS.PoolMgr
local PoolMgr = TBS.CreateSingleton("PoolMgr")
local this = PoolMgr
function PoolMgr.OnCreate()
    ---@type table<string,GameObject[]>
    this.resObjList = {}        --资源缓存
    this.resObjRequestList = {} --资源加载回调
    ---@type table<number,TBS.EffectBase[]>
    this.cacheEffectList = {} --特效缓存
    ---@type TBS.Buffer[]
    this.cacheBufferList = {}   --buff缓存
    this.staticId = 0
    ---@type EffectGCompItem[]
    this.cacheEffectGCompList = {}  --fgui控件节点
    local go = GameObject.New("pool")
    go:SetActive(false)
    this.objRoot = go.transform
    this.cacheSkillList = {}
end
function PoolMgr.OnDestroy()
    if this.resObjList then
        for k,v in pairs(this.resObjList) do
            for index,go in pairs(v) do
                destroy(go)
            end
        end
    end

    if this.resObjRequestList then
        for k,v in pairs(this.resObjRequestList) do
            TablePool.ReleaseDeeper(v,false)
        end
    end
    if this.cacheEffectGCompList then
        for k,v in pairs(this.cacheEffectGCompList) do
            v.gameObject = nil
            v.wrapper:Dispose()
            v.gComp:Dispose()
            v.wrapper = nil
            v.root = nil
            v.gComp = nil
        end
    end
    if not HelperFunc.IsNull(this.objRoot) then
        destroy(this.objRoot.gameObject)
    end
    this.objRoot = nil
    this.cacheEffectGCompList = nil
    this.resObjRequestList = nil
    this.resObjList = nil
    this.cacheSkillList = nil

end
--region resObj
---@private
function PoolMgr.GetUniqueId()
    this.staticId = this.staticId + 1
    return this.staticId
end
function PoolMgr.LoadPrefabFromPool(path,callback,tb,param)
    local _list = this.resObjList[path]
    if _list and #_list > 0 then
        local obj = table.remove(_list)
        obj:SetActive(true)
        if callback then
            callback(tb,obj,param)
        end
        return 0
    end
    local id = this.LoadPrefab(path,callback,tb,param)
    return id
end
---@param obj GameObject
function PoolMgr.ReturnPrefabToPool(path,obj)
    if path == "" or not obj then return end
    if Util.IsNull(obj) then return end
    obj:SetActive(false)
    obj.transform:SetParent(this.objRoot,false)
    local _list = this.resObjList[path]
    if not _list then
        _list = {}
        this.resObjList[path] = _list
    end
    table.insert(_list,obj)
end
---@private
function PoolMgr.LoadCallback(path,obj)
    if this.resObjRequestList ~= nil then
        local _list = TablePool.Get()
        for k,v in pairs(this.resObjRequestList) do
            _list[k] = v
        end
        for k,data in pairs(_list) do
            if data.path == path then
                obj = newObject(obj)
                data.callback(data.tb,obj,data.param)
                TablePool.ReleaseDeeper(data,false)
                this.resObjRequestList[k] = nil
            end
        end
        TablePool.ReleaseDeeper(_list,false)
    end
end
---@private
function PoolMgr.LoadPrefab(path,callback,tb,param)
    local id = this.GetUniqueId()
    local _table = TablePool.Get()
    _table.callback = callback
    _table.tb = tb
    _table.param = param
    _table.path = path
    this.resObjRequestList[id] = _table
    resMgr:LoadModelPrefab(path,function(obj1)
        this.LoadCallback(path,obj1)
    end)
    return id
end
function PoolMgr.CancelLoad(requestId)
    if requestId == nil then return end
    TablePool.ReleaseDeeper(this.resObjRequestList[requestId],false)
    this.resObjRequestList[requestId] = nil
end

--endregion resObj
--region effectBase
---@return TBS.EffectBase
function PoolMgr.GetEffectFromPool(id,_type)
    local _list = this.cacheEffectList[_type]
    if _list and #_list > 0 then
        local eff = table.remove(_list)
        eff.id = id
        return eff
    end
    local eff = TBS.Config.EffectMapping[_type]
    if not eff then
        logError("未注册该Effect ".._type)
        return nil
    end
    return eff.New(id,_type)
end
---@param effect TBS.EffectBase
function PoolMgr.ReturnEffectToPool(effect)
    if effect == nil then return end
    local _list = this.cacheEffectList[effect.effectType]
    if not _list then
        _list = {}
        this.cacheEffectList[effect.effectType] = _list
    end
    for k,v in pairs(_list) do
        if v == effect then
            return
        end
    end
    table.insert(_list,effect)
end
--endregion effectBase
--region Buffer
---@return TBS.Buffer
function PoolMgr.GetBufferFromPool()
    local _list = this.cacheBufferList
    if _list and #_list > 0 then
        local b = table.remove(_list)
        return b
    end
    return TBS.Buffer.New()
end
---@param buffer TBS.Buffer
function PoolMgr.ReturnBufferToPool(buffer)
    if buffer == nil then return end
    table.insert(this.cacheBufferList,buffer)
end
--endregion Buffer
---@return EffectGCompItem
function PoolMgr.GetEffectGCompFromPool()
    local _list = this.cacheEffectGCompList
    if _list and #_list > 0 then
        local b = table.remove(_list)
        b.gComp.visible = true
        return b
    end
    local go = newGComponent("EffectTemplate","UIInvasion")
    local tb = {gComp = go,
                wrapper = GoWrapper.New(),
                root = go:GetChild("effect"),
                gameObject = nil}
    return tb
end
---@param item EffectGCompItem
function PoolMgr.ReturnEffectGCompToPool(item)
    if item == nil then return end
    item.gComp.visible = false
    table.insert(this.cacheEffectGCompList,item)
end
---@return TBS.Skill
function PoolMgr.GetSkillFromPool(skillId)
    local _list = this.cacheSkillList[skillId]
    if _list and #_list > 0 then
        return table.remove(_list)
    end
    local skill = TBS.Skill.New()
    skill:OnCreate(skillId)
    return skill
end
---@param skill TBS.Skill
function PoolMgr.ReturnSkillToPool(skill)
    if not skill then return end
    local _list = this.cacheSkillList[skill.skillId]
    if not _list then
        _list = {}
        this.cacheSkillList[skill.skillId] = _list
    end
    table.insert(_list,skill)
end